﻿using CSRedis;
using Project.Net.Application;
using System;
using System.Threading.Tasks;
namespace Project.Net.Inra.Redis
{
    public class RedisRepository : IRedisRepository
    {
        private readonly CSRedisClient _redisClient;

        /// <summary>
        /// 初始化 RedisRepository 实例。
        /// </summary>
        /// <param name="connectionString">Redis 的连接字符串。</param>
        public RedisRepository()
        {
            string connectionString = "127.0.0.1:6379,defaultDatabase=1";
            _redisClient = new CSRedisClient(connectionString);
        }

        /// <summary>
        /// 异步获取 Redis 中指定键的字符串值。
        /// </summary>
        /// <param name="key">要获取值的键。</param>
        /// <returns>键对应的字符串值，如果键不存在则返回 null。</returns>
        public async Task<T> GetAsync<T>(string key)
        {
            try
            {
                var result = await _redisClient.GetAsync<T>(key);
                return result;
            }
            catch (Exception ex)
            {

                throw;
            }
           
        }

        /// <summary>
        /// 异步设置 Redis 中指定键的字符串值。
        /// </summary>
        /// <param name="key">要设置值的键。</param>
        /// <param name="value">要设置的字符串值。</param>
        public async Task SetStringAsync(string key, string value, TimeSpan? expiry = null)
        {
            if (!expiry.HasValue)
            {
                await _redisClient.SetAsync(key, value);
            }
            else
            {
                await _redisClient.SetAsync(key, value, expiry.Value);
            }
        }

        /// <summary>
        /// 异步获取 Redis 中指定哈希键的指定字段的字符串值。
        /// </summary>
        /// <param name="key">哈希键。</param>
        /// <param name="field">要获取值的字段。</param>
        /// <returns>字段对应的字符串值，如果字段不存在则返回 null。</returns>
        public async Task<string> GetHashFieldAsync(string key, string field)
        {
            return await _redisClient.HGetAsync(key, field);
        }

        /// <summary>
        /// 异步设置 Redis 中指定哈希键的指定字段的字符串值。
        /// </summary>
        /// <param name="key">哈希键。</param>
        /// <param name="field">要设置值的字段。</param>
        /// <param name="value">要设置的字符串值。</param>
        public async Task SetHashFieldAsync(string key, string field, string value)
        {
            await _redisClient.HSetAsync(key, field, value);
        }

        /// <summary>
        /// 异步检查 Redis 中是否存在指定键。
        /// </summary>
        /// <param name="key">要检查的键。</param>
        /// <returns>如果键存在则返回 true，否则返回 false。</returns>
        public async Task<bool> KeyExistsAsync(string key)
        {
            return await _redisClient.ExistsAsync(key);
        }

        /// <summary>
        /// 异步删除 Redis 中指定键。
        /// </summary>
        /// <param name="key">要删除的键。</param>
        public async Task DeleteKeyAsync(string key)
        {
            await _redisClient.DelAsync(key);
        }
        /// <summary>
        /// 向指定的Redis列表中追加一个字符串值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public Task AppendToListAsync(string key, string value)
        {
            _redisClient.RPush(key, value);
            return Task.CompletedTask;
        }
        /// <summary>
        /// 从Redis列表的左侧移除并返回一个元素
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public Task<string> PopFromListLeftAsync(string key)
        {
            return _redisClient.LPopAsync(key);
        }

        public Task<string> PopFromListRightAsync(string key)
        {
            return _redisClient.RPopAsync(key);
        }
        /// <summary>
        /// 将指定成员异步添加到Redis集合中。
        /// </summary>
        /// <param name="key">集合的键。</param>
        /// <param name="members">要添加的成员数组。</param>
        /// <returns>一个已完成的任务。</returns>
        public Task AddToSetAsync(string key, params string[] members)
        {
            _redisClient.SAdd(key, members);
            return Task.CompletedTask;
        }
        /// <summary>
        /// 从Redis集合中异步移除指定成员。
        /// </summary>
        /// <param name="key">集合的键。</param>
        /// <param name="members">要移除的成员数组。</param>
        /// <returns>一个已完成的任务。</returns>
        public Task RemoveFromSetAsync(string key, params string[] members)
        {
            _redisClient.SRem(key, members);
            return Task.CompletedTask;
        }
        /// <summary>
        /// 异步检查指定成员是否是Redis集合的成员。
        /// </summary>
        /// <param name="key">集合的键。</param>
        /// <param name="member">要检查的成员。</param>
        /// <returns>一个任务，返回一个布尔值，指示成员是否存在于集合中。</returns>
        public Task<bool> IsSetMemberAsync(string key, string member)
        {
            return _redisClient.SIsMemberAsync(key, member);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <param name="scoreMembers"></param>
        /// <returns></returns>
        public Task AddToSortedSetAsync(string key, params (double score, string member)[] scoreMembers)
        {
            foreach (var (score, member) in scoreMembers)
            {
                _redisClient.ZAdd(key, (Convert.ToDecimal(score), member));
            }
            return Task.CompletedTask;
        }

        public Task RemoveFromSortedSetAsync(string key, params string[] members)
        {
            _redisClient.ZRem(key, members);
            return Task.CompletedTask;
        }

        public Task<string[]> GetSortedSetRangeByRankAsync(string key, long start, long stop)
        {
            return _redisClient.ZRangeAsync(key, start, stop);
        }

        public Task<string[]> GetSortedSetRangeByScoreAsync(string key, double min, double max)
        {
            return _redisClient.ZRangeByScoreAsync(key, (decimal)min, (decimal)max);
        }

        public Task ExpireKeyAsync(string key, TimeSpan expiry)
        {
            _redisClient.Expire(key, expiry);
            return Task.CompletedTask;
        }

        public Task<TimeSpan?> GetKeyTimeToLiveAsync(string key)
        {
            var ttl = _redisClient.Ttl(key);
            return Task.FromResult(ttl == -1 ? (TimeSpan?)null : TimeSpan.FromSeconds(ttl));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<long> IncrementAsync(string key)
        {
            return await _redisClient.IncrByAsync(key);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<long> DecrementAsync(string key)
        {
            return await _redisClient.IncrByAsync(key,-1);
        }

        /// <summary>
        /// 异步获取指定键的字符串值
        /// </summary>
        /// <param name="key">要获取值的键</param>
        /// <returns>键对应的字符串值，如果键不存在则返回null</returns>
        public Task<string> GetStringAsync(string key)
        {
            return _redisClient.GetAsync(key);
        }

        public async Task<bool> SetAddAsync(string key, string value)
        {
            // 向Redis集合中添加一个成员
            var result= await _redisClient.SAddAsync(key, value);
            return result > 0;
        }
    }
}
